<?php
declare(strict_types=1);
/**
 * MineAdmin is committed to providing solutions for quickly building web applications
 * Please view the LICENSE file that was distributed with this source code,
 * For the full copyright and license information.
 * Thank you very much for using MineAdmin.
 *
 * @Author X.Mo<root@imoi.cn>
 * @Link   https://gitee.com/xmo/MineAdmin
 */

namespace App\Goods\Mapper;

use App\Goods\Model\GoodsInfo;
use App\Goods\Model\GoodsSku;
use App\Goods\Model\GoodsSpec;
use App\Lib\Library\Helper;
use Hyperf\Database\Model\Builder;
use Hyperf\DbConnection\Db;
use Mine\Abstracts\AbstractMapper;
use Mine\MineModel;

/**
 * 商品列表Mapper类
 */
class GoodsInfoMapper extends AbstractMapper
{
    /**
     * @var GoodsInfo
     */
    public $model;
    const MULTI = 20;
    const SINGLE = 10;
    private static $storeId = 1001;

    use \App\Lib\Library\UseZyLib;

    public function assignModel()
    {
        $this->model = GoodsInfo::class;
    }

    /**
     * 搜索处理器
     * @param Builder $query
     * @param array $params
     * @return Builder
     */
    public function handleSearch(Builder $query, array $params): Builder
    {

        // 商品ID
        if (isset($params['goods_id']) && filled($params['goods_id'])) {
            $query->where('goods_id', '=', $params['goods_id']);
        }

        // 商品类型(10实物商品)
        if (isset($params['goods_type']) && filled($params['goods_type'])) {
            $query->where('goods_type', '=', $params['goods_type']);
        }

        // 商品名称
        if (isset($params['goods_name']) && filled($params['goods_name'])) {
            $query->where('goods_name', 'like', '%' . $params['goods_name'] . '%');
        }

        // 商品编码
        if (isset($params['goods_no']) && filled($params['goods_no'])) {
            $query->where('goods_no', 'like', '%' . $params['goods_no'] . '%');
        }

        // 主图视频ID
        if (isset($params['video_id']) && filled($params['video_id'])) {
            $query->where('video_id', '=', $params['video_id']);
        }

        // 主图视频ID
        if (isset($params['video_cover_id']) && filled($params['video_cover_id'])) {
            $query->where('video_cover_id', '=', $params['video_cover_id']);
        }

        // 商品卖点
        if (isset($params['selling_point']) && filled($params['selling_point'])) {
            $query->where('selling_point', 'like', '%' . $params['selling_point'] . '%');
        }

        // 商品规格(10单规格 20多规格)
        if (isset($params['spec_type']) && filled($params['spec_type'])) {
            $query->where('spec_type', '=', $params['spec_type']);
        }

        // 商品价格(最低)
        if (isset($params['goods_price_min']) && filled($params['goods_price_min'])) {
            $query->where('goods_price_min', '=', $params['goods_price_min']);
        }

        // 商品价格(最高)
        if (isset($params['goods_price_max']) && filled($params['goods_price_max'])) {
            $query->where('goods_price_max', '=', $params['goods_price_max']);
        }

        // 划线价格(最低)
        if (isset($params['line_price_min']) && filled($params['line_price_min'])) {
            $query->where('line_price_min', '=', $params['line_price_min']);
        }

        // 划线价格(最高)
        if (isset($params['line_price_max']) && filled($params['line_price_max'])) {
            $query->where('line_price_max', '=', $params['line_price_max']);
        }

        // 库存总量(包含所有sku)
        if (isset($params['stock_total']) && filled($params['stock_total'])) {
            $query->where('stock_total', '=', $params['stock_total']);
        }

        // 库存计算方式(10下单减库存 20付款减库存)
        if (isset($params['deduct_stock_type']) && filled($params['deduct_stock_type'])) {
            $query->where('deduct_stock_type', '=', $params['deduct_stock_type']);
        }

        // 是否开启限购(0未开启 1已开启)
        if (isset($params['is_restrict']) && filled($params['is_restrict'])) {
            $query->where('is_restrict', '=', $params['is_restrict']);
        }

        // 总限购数量(0为不限制)
        if (isset($params['restrict_total']) && filled($params['restrict_total'])) {
            $query->where('restrict_total', '=', $params['restrict_total']);
        }

        // 每单限购数量(0为不限制)
        if (isset($params['restrict_single']) && filled($params['restrict_single'])) {
            $query->where('restrict_single', '=', $params['restrict_single']);
        }

        // 商品详情
        if (isset($params['content']) && filled($params['content'])) {
            $query->where('content', '=', $params['content']);
        }

        // 初始销量
        if (isset($params['sales_initial']) && filled($params['sales_initial'])) {
            $query->where('sales_initial', '=', $params['sales_initial']);
        }

        // 实际销量
        if (isset($params['sales_actual']) && filled($params['sales_actual'])) {
            $query->where('sales_actual', '=', $params['sales_actual']);
        }

        // 配送模板ID
        if (isset($params['delivery_id']) && filled($params['delivery_id'])) {
            $query->where('delivery_id', '=', $params['delivery_id']);
        }

        // 是否开启积分赠送(1开启 0关闭)
        if (isset($params['is_points_gift']) && filled($params['is_points_gift'])) {
            $query->where('is_points_gift', '=', $params['is_points_gift']);
        }

        // 是否允许使用积分抵扣(1允许 0不允许)
        if (isset($params['is_points_discount']) && filled($params['is_points_discount'])) {
            $query->where('is_points_discount', '=', $params['is_points_discount']);
        }

        // 积分抵扣设置(0默认抵扣 1单独设置抵扣)
        if (isset($params['is_alone_points_discount']) && filled($params['is_alone_points_discount'])) {
            $query->where('is_alone_points_discount', '=', $params['is_alone_points_discount']);
        }

        // 单独设置积分抵扣的配置
        if (isset($params['points_discount_config']) && filled($params['points_discount_config'])) {
            $query->where('points_discount_config', 'like', '%' . $params['points_discount_config'] . '%');
        }

        // 是否开启会员折扣(1开启 0关闭)
        if (isset($params['is_enable_grade']) && filled($params['is_enable_grade'])) {
            $query->where('is_enable_grade', '=', $params['is_enable_grade']);
        }

        // 会员折扣设置(0默认等级折扣 1单独设置折扣)
        if (isset($params['is_alone_grade']) && filled($params['is_alone_grade'])) {
            $query->where('is_alone_grade', '=', $params['is_alone_grade']);
        }

        // 单独设置折扣的配置
        if (isset($params['alone_grade_equity']) && filled($params['alone_grade_equity'])) {
            $query->where('alone_grade_equity', '=', $params['alone_grade_equity']);
        }

        // 是否单独设置配送方式(0关闭 1开启)
        if (isset($params['is_ind_delivery_type']) && filled($params['is_ind_delivery_type'])) {
            $query->where('is_ind_delivery_type', '=', $params['is_ind_delivery_type']);
        }

        // 商品配送方式(仅单独设置时有效)
        if (isset($params['delivery_type']) && filled($params['delivery_type'])) {
            $query->where('delivery_type', 'like', '%' . $params['delivery_type'] . '%');
        }

        // 商品状态(10上架 20下架)
        if (isset($params['status']) && filled($params['status'])) {
            $query->where('status', '=', $params['status']);
        }

        // 排序(数字越小越靠前)
        if (isset($params['sort']) && filled($params['sort'])) {
            $query->where('sort', '=', $params['sort']);
        }

        // 是否删除
        if (isset($params['is_delete']) && filled($params['is_delete'])) {
            $query->where('is_delete', '=', $params['is_delete']);
        }

        // 商城ID
        if (isset($params['store_id']) && filled($params['store_id'])) {
            $query->where('store_id', '=', $params['store_id']);
        }

        // 创建时间
        if (isset($params['create_time']) && filled($params['create_time'])) {
            $query->where('create_time', '=', $params['create_time']);
        }

        // 更新时间
        if (isset($params['update_time']) && filled($params['update_time'])) {
            $query->where('update_time', '=', $params['update_time']);
        }

        return $query;
    }

    /**
     * 新增数据.
     */
    public function saveData(array $data): mixed
    {
        $value = $this->transactionDb(function () use ($data) {
            $newData = $this->createData($data);
            $oldData = $newData;
            $this->filterExecuteAttributes($newData, $this->getModel()->incrementing);
            $model = $this->model::create($newData);
            // 新增商品与分类关联
            \App\Goods\Model\GoodsCategoryRel::increased((int)$model['id'], $oldData['categoryIds']);
            // 新增商品sku信息
            \App\Goods\Model\GoodsSku::add((int)$model['id'], $oldData['spec_type'], $oldData['newSkuList']);
            // 新增商品与规格关联
            \App\Goods\Model\GoodsSpecRel::increased((int)$model['id'], $oldData['newSpecList']);
            return true;
        });
        return $value;
    }

    public function update(mixed $id, array $data): bool
    {
        $value = $this->transactionDb(function () use ($id, $data) {
            $data = $this->createData($data);
            // 新增商品与分类关联
            \App\Goods\Model\GoodsCategoryRel::increased((int)$id, $data['categoryIds']);
            // 新增商品sku信息
            \App\Goods\Model\GoodsSku::add((int)$id, $data['spec_type'], $data['newSkuList']);
            // 新增商品与规格关联
            \App\Goods\Model\GoodsSpecRel::increased((int)$id, $data['newSpecList']);
            $this->filterExecuteAttributes($data, true);
            return $this->model::find($id)->update($data) > 0;
        });
        return $value;
    }

    /**
     * 读取一条数据.
     */
    public function read(mixed $id, array $column = ['*']): ?MineModel
    {
        return ($model = $this->model::find($id, $column)) ? $model : null;
    }
    private function createData(array $data): array
    {
        $storeId = user()->getId();
        // 默认数据
        $data = array_merge($data, [
            'line_price' => $data['line_price'] ?? 0,
            'content' => $data['content'] ?? '',
            'newSpecList' => [],
            'newSkuList' => [],
            'store_id' => $storeId,
        ]);
        // 整理商品的价格和库存总量
        if ($data['spec_type'] == self::MULTI) {
            $data['stock_total'] = \App\Goods\Model\GoodsSku::getStockTotal($data['specData']['skuList']);
            [$data['goods_price_min'], $data['goods_price_max']] = \App\Goods\Model\GoodsSku::getGoodsPrices($data['specData']['skuList']);
            [$data['line_price_min'], $data['line_price_max']] = \App\Goods\Model\GoodsSku::getLinePrices($data['specData']['skuList']);
        } elseif ($data['spec_type'] == self::SINGLE) {
            $data['goods_price_min'] = $data['goods_price_max'] = $data['goods_price'];
            $data['line_price_min'] = $data['line_price_max'] = $data['line_price'];
            $data['stock_total'] = $data['stock_num'];
        }
        // 规格和sku数据处理
        if ($data['spec_type'] == self::MULTI) {
            // 验证规格值是否合法
            GoodsSpec::checkSpecData($data['specData']['specList']);
            // 生成多规格数据 (携带id)
            $data['newSpecList'] = GoodsSpec::getNewSpecList($data['specData']['specList'], $storeId);
            // 生成skuList (携带goods_sku_id)
            $data['newSkuList'] = GoodsSku::getNewSkuList($data['newSpecList'], $data['specData']['skuList']);
        } elseif ($data['spec_type'] == self::SINGLE) {
            // 生成skuItem
            $data['newSkuList'] = Helper::pick($data, ['goods_price', 'line_price', 'stock_num', 'goods_weight']);
        }
        return $data;
    }
}